package com.vdongchina.thread.Lock;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 可重入读写锁
 * <p>
 * 公平性/重入性/锁降级
 * <p>
 * 锁降级--->写锁直接降级为读锁,不是重新获取读锁
 */
public class ReentrantReadWriteLockDemo {

    static Map<String, Object> map = new HashMap<>();
    static ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
    static Lock r = reentrantReadWriteLock.readLock();
    static Lock w = reentrantReadWriteLock.writeLock();

    /**
     * 读锁
     *
     * @param key
     * @return
     */
    public static final Object get(String key) {
        r.lock();
        try {
            return map.get(key);
        } finally {
            r.unlock();
        }
    }

    /**
     * 写锁
     *
     * @param key
     * @param value
     * @return
     */
    public static final Object put(String key, Object value) {
        w.lock();
        try {
            return map.put(key, value);
        } finally {
            w.unlock();
        }

    }

    public static final void clear() {
        w.lock();
        try {
            map.clear();
        } finally {
            w.unlock();
        }
    }


    /**
     * 锁降级
     * 确保修改后的数据能够回显回去,防止写锁释放后被其他写锁修改了数据,导致回显数据异常
     *
     */
    public void processData() {
        r.lock();
        if (true) {
            r.unlock();
            w.lock();
            try {
                r.lock();  //只有该线程能获取读锁,其他线程都被堵塞
            } finally {
                w.unlock();
            }
            //锁降级完成
        }
        try {

        } finally {
            r.unlock();
        }
    }
}
